from typing import List
from .Class_SVDObject import SVDObject
from .Class_EnumeratedValue import EnumeratedValue
from .Class_EnumeratedValues import EnumeratedValues
from .Class_Field import Field
from xml.dom.minidom import Document as XMLFile


class Register(SVDObject):
    def __init__(self, name: str = "", description: str = "", addressOffset: str = "", resetValue: str = "",  father: str = "",  dim: str = "",  dimIncrement: str = "",  dimIndex: str = ""):
        super().__init__(name)
        self.type = "Field"
        self.father = father
        self.description = description
        self.addressOffset = addressOffset
        self.resetValue = resetValue
        self.dim = dim
        self.dimIncrement = dimIncrement
        self.dimIndex = dimIndex
        self.fields : List[Field] = []
    def __repr__(self):
        return (f"Register(name={self.name}, father={self.father}, "
                f"description={self.description}, addressOffset={self.addressOffset}, "
                f"resetValue={self.resetValue}")
    def setAddressOffset(self, addressOffset: str):
        self.addressOffset = addressOffset
        
    def SetResetValue(self, resetValue: str):
        self.resetValue = resetValue
        
    def SetFather(self, father: str):
        self.father = father
        for field in self.fields:
            field.SetFather(self.myself())
    
    def SetDescription(self, description: str):
        self.description = description

    def AddField(self, field : Field):
        field.SetFather(self.myself())
        self.fields.append(field)

    def ValidCheck(self):        
        errcnt = super().ValidCheck()
        for Field in self.fields:
            errcnt += Field.ValidCheck();
        return errcnt
    def toString(self, tablevel) -> str:
        xml_output = (
            f"{self.TabsString(tablevel)}<register><!--{self.name}-->\n"
            f"{self.TabsString(tablevel + 1)}<name>{self.name}</name>\n"
        )
        
        if self.dim :
            xml_output += f"{self.TabsString(tablevel + 1)}<dim>{self.dim}</dim>\n"
        if self.dimIncrement :
            xml_output += f"{self.TabsString(tablevel + 1)}<dimIncrement>{self.dimIncrement}</dimIncrement>\n"
        if self.dimIndex :
            xml_output += f"{self.TabsString(tablevel + 1)}<dimIndex>{self.dimIndex}</dimIndex>\n"
        
        # 仅在描述不为空时输出描述
        if self.description:
            xml_output += f"{self.TabsString(tablevel + 1)}<description>{self.description}</description>\n"
        
        xml_output += (
            f"{self.TabsString(tablevel + 1)}<addressOffset>{self.addressOffset}</addressOffset>\n"
            f"{self.TabsString(tablevel + 1)}<resetValue>{self.resetValue}</resetValue>\n"
            f"{self.TabsString(tablevel + 1)}<fields>\n"
        )
        
        # 输出所有字段
        for field in self.fields:
            xml_output += field.toString(tablevel + 2)  # 调用 Field 的 toString
        
        xml_output += (
            f"{self.TabsString(tablevel + 1)}</fields>\n"
            f"{self.TabsString(tablevel)}</register>\n"
        )
        
        return xml_output
    
    def toXmlObj(self, xmlfather):
        doc = xmlfather.ownerDocument
        
        register_element = doc.createElement('register')
        
        
        if self.dim :
            dim_element = doc.createElement('dim')
            dim_text = doc.createTextNode(str(self.dim))
            dim_element.appendChild(dim_text)
            register_element.appendChild(dim_element)
        if self.dimIncrement :
            dim_element = doc.createElement('dimIncrement')
            dim_text = doc.createTextNode(str(self.dimIncrement))
            dim_element.appendChild(dim_text)
            register_element.appendChild(dim_element)
        if self.dimIndex :
            dim_element = doc.createElement('dimIndex')
            dim_text = doc.createTextNode(str(self.dimIndex))
            dim_element.appendChild(dim_text)
            register_element.appendChild(dim_element)      
        
        name_element = doc.createElement('name')
        name_text = doc.createTextNode(self.name)
        name_element.appendChild(name_text)
        register_element.appendChild(name_element)        
        
        # 仅在描述不为空时输出描述
        if self.description:
            description_element = doc.createElement('description')
            description_text = doc.createTextNode(self.description)
            description_element.appendChild(description_text)
            register_element.appendChild(description_element)
        
        address_offset_element = doc.createElement('addressOffset')
        address_offset_text = doc.createTextNode(self.addressOffset)
        address_offset_element.appendChild(address_offset_text)
        register_element.appendChild(address_offset_element)
        
        reset_value_element = doc.createElement('resetValue')
        reset_value_text = doc.createTextNode(self.resetValue)
        reset_value_element.appendChild(reset_value_text)
        register_element.appendChild(reset_value_element)
        
        # 输出所有字段
        fields_element = doc.createElement('fields')
        for field in self.fields:
            field.toXmlObj(fields_element)
        register_element.appendChild(fields_element)
        
        xmlfather.appendChild(register_element)

    @staticmethod
    def GetTestObject():
        # 创建一个 Register 的实例
        register = Register(
            name="GCR",
            description="The GCR register contains control bits that apply to both LIN and UART modes. The GCR register is read-only in Normal mode and can be written only in Initialization mode.",
            addressOffset="0x8c",
            resetValue="0x00000000"
        )
        
        test_field = Field.GetTestObject()  # 获取测试字段
        register.AddField(test_field)  # 将测试字段添加到寄存器
        register.AddField(test_field)  # 将测试字段添加到寄存器
        
        return register
        
    @staticmethod
    def TestString():
        testObject = Register.GetTestObject()
        print(testObject.toString(2))